/**
 * @author: Miss.杨
 * @date: 2025年3月18日 22:21:07
 * @description: 
 */
package com.sheepone.monitor.audit.listener;

import java.lang.reflect.Method;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.lang.NonNull;

import com.sheepone.monitor.audit.anno.scene.AfterScene;
import com.sheepone.monitor.audit.anno.scene.AuditSceneProcessor;
import com.sheepone.monitor.audit.anno.scene.BeforeScene;
import com.sheepone.monitor.audit.aspect.AuditCommitAspect;
import com.sheepone.monitor.audit.core.entities.AuditLogMessage;

/**
 * @author: Miss.杨
 * @date: 2025年3月18日 22:21:07
 * @description: 监听Spring容器初始化完成事件
 */
public class SceneProcessorApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
    @Resource
    AuditCommitAspect aspect;

    @Override
    public void onApplicationEvent(@NonNull ContextRefreshedEvent event) {
        ApplicationContext applicationContext = event.getApplicationContext();
        Map<String, Object> eventListenerMap = applicationContext.getBeansWithAnnotation(AuditSceneProcessor.class);
        for (Object bean : eventListenerMap.values()) {
            Class<?> beanClass = bean.getClass();
            Method[] methods = beanClass.getDeclaredMethods();

            for (Method method : methods) {
                BeforeScene before = method.getDeclaredAnnotation(BeforeScene.class);
                AfterScene after = method.getDeclaredAnnotation(AfterScene.class);
                if (before == null && after == null) {
                    continue;
                }
                if (before != null && after != null) {
                    // TODO 抛出异常
                }
                checkParameters(method);
                method.setAccessible(true);
                if (before != null) {
                    aspect.registerBeforeSceneProcessor(before.scene(), bean, method);
                }
                if (after != null) {
                    aspect.registerAfterSceneProcessor(after.scene(), bean, method);
                }
            }
        }
    }

    private void checkParameters(Method method) {
        for (Class<?> parameterTypes : method.getParameterTypes()) {
            if (parameterTypes.equals(AuditLogMessage.class)) {
                return;
            }
        }
        // TODO 抛出异常
    }
}
